using GiteeApi.Models;
using GiteeApi.Services;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System;
using System.IO;
using System.Net;
using System.Reflection;
using System.Text;
using GiteeApi.Utils;
using Microsoft.AspNetCore.Http;
using Swashbuckle.AspNetCore.Filters;

namespace GiteeApi
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            #region Swagger

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "GiteeApi", Version = "v1" });
                // 获取xml文件名
                var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                // 获取xml文件路径
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                // 添加控制器层注释，true表示显示控制器注释
                c.IncludeXmlComments(xmlPath, true);
                
                // 开启权限小锁
                c.OperationFilter<AddResponseHeadersFilter>();
                c.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();
                
                // 在 header 中添加 token，传递到后台
                c.OperationFilter<SecurityRequirementsOperationFilter>();
                c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme()
                {
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.ApiKey,
                    Description = "Bearer Token",
                    Name = "Authorization",
                    BearerFormat = "JWT",
                    Scheme = "Bearer"
                });
            });

            #endregion

            #region 注册 JWT 认证服务

            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    // JWT 认证参数
                    var secretByte = Encoding.UTF8.GetBytes(Configuration["Authentication:SecretKey"]);
                    options.TokenValidationParameters = new TokenValidationParameters()
                    {
                        // 验证发布者
                        ValidateIssuer = true,
                        ValidIssuer = Configuration["Authentication:issuer"],

                        // 验证发布对象
                        ValidateAudience = true,
                        ValidAudience = Configuration["Authentication:audience"],

                        // 验证 Token 是否过期
                        ValidateLifetime = true,

                        // 私钥加密
                        IssuerSigningKey = new SymmetricSecurityKey(secretByte)
                    };
                });

            #endregion
            
            #region 跨域配置

            // 设置允许所有来源跨域
            services.AddCors(options => options.AddPolicy("CorsPolicy",
                builder =>
                {
                    builder
                        .AllowAnyMethod()
                        .AllowAnyHeader()
                        .SetIsOriginAllowed(_ => true) // = AllowAnyOrigin()
                        .AllowCredentials();
                }));

            #endregion

            #region 注入实例

            services.AddTransient<UserServices>();
            services.AddTransient<AccessTokenServices>();
            services.AddTransient<giteeapiContext>();
            services.AddTransient<EmailUtil>();
            services.AddTransient<JWTUtil>();
            services.AddTransient<RedisCacheHelper>();
            services.AddTransient<GiteeAPIServices>();

            #endregion
            
            // 注册 AutoMapper，扫描 Profile 文件
            services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
            
            // HttClient
            services.AddHttpClient();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            
            // 使用跨域配置
            app.UseCors("CorsPolicy");

            // Swagger 使用
            app.UseSwagger();
            app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "GiteeAPI v1"));

            app.UseRouting();
            // 认证
            app.UseAuthentication();
            // 授权
            app.UseAuthorization();

            app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
        }
    }
}